#include "pleiades.h"
#include "CuTest.h"
#include <pthread.h>

pleiades_client_t *shared_client; 
pleiades_event_handler_t *shared_handler;

static void contentsModified(pleiades_lock_event_data_t *eventData)
{
	printf("==== contents modified ===================================\n");
	printf("creator = %s\n", eventData->creator);
	printf("lock_id = %s\n", eventData->lock_id);
	printf("generation_number = %ld\n", eventData->generation_number);
	printf("type = %d\n", eventData->type);
	printf("is_dir = %d\n", eventData->is_dir);
	printf("===================================================\n");
}

static void nodeAdded(pleiades_lock_event_data_t *eventData)
{
	printf("==== node added ===================================\n");
	printf("creator = %s\n", eventData->creator);
	printf("lock_id = %s\n", eventData->lock_id);
	printf("generation_number = %ld\n", eventData->generation_number);
	printf("type = %d\n", eventData->type);
	printf("is_dir = %d\n", eventData->is_dir);
	printf("===================================================\n");
}

static void nodeRemoved(pleiades_lock_event_data_t *eventData)
{
	printf("==== node removed ===================================\n");
	printf("creator = %s\n", eventData->creator);
	printf("lock_id = %s\n", eventData->lock_id);
	printf("generation_number = %ld\n", eventData->generation_number);
	printf("type = %d\n", eventData->type);
	printf("is_dir = %d\n", eventData->is_dir);
	printf("===================================================\n");
}

static void nodeModified(pleiades_lock_event_data_t *eventData)
{
	printf("==== node modified ===================================\n");
	printf("creator = %s\n", eventData->creator);
	printf("lock_id = %s\n", eventData->lock_id);
	printf("generation_number = %ld\n", eventData->generation_number);
	printf("type = %d\n", eventData->type);
	printf("is_dir = %d\n", eventData->is_dir);
	printf("===================================================\n");
}

static void masterFailover()
{
	printf("==== master failover ===============================\n");
}

static void sessionWarning()
{
	printf("==== session warning ===============================\n");
}

static void sessionSafe()
{
	printf("==== session safe ===============================\n");
}

static void sessionExpired()
{
	printf("==== session expired ===============================\n");
}

static void clientExpired(pleiades_lock_event_data_t *eventData)
{
	printf("==== client expired ===================================\n");
	printf("creator = %s\n", eventData->creator);
	printf("lock_id = %s\n", eventData->lock_id);
	printf("generation_number = %ld\n", eventData->generation_number);
	printf("type = %d\n", eventData->type);
	printf("is_dir = %d\n", eventData->is_dir);
	printf("===================================================\n");
}

static void lockExpired(pleiades_lock_event_data_t *eventData)
{
	printf("==== lock expired ===================================\n");
	printf("creator = %s\n", eventData->creator);
	printf("lock_id = %s\n", eventData->lock_id);
	printf("generation_number = %ld\n", eventData->generation_number);
	printf("type = %d\n", eventData->type);
	printf("is_dir = %d\n", eventData->is_dir);
	printf("===================================================\n");
}

static void eventMonitor(pleiades_event_t event, pleiades_lock_event_data_t *eventData)
{
	printf("***** event monitor *****************************\n");
	printf("creator = %s\n", eventData->creator);
	printf("lock_id = %s\n", eventData->lock_id);
	printf("generation_number = %ld\n", eventData->generation_number);
	printf("type = %d\n", eventData->type);
	printf("is_dir = %d\n", eventData->is_dir);
	printf("*************************************************\n");
}

void TestPleiades(CuTest *tc)
{
    const char* path1 = "/a";
    const char* path2 = "/b";
    const char* path3 = "/c"; 
    int result = 0;
	char contents[1024];
	char hostname[256];
	pleiades_lock_meta_data_t *metaData;
    pleiades_client_t *client; 
	pleiades_event_handler_t *handler;
    int numEntries = 0;
	
	client = pleiades_create_client("default", NULL);
	CuAssertTrue(tc, client != NULL);

	/* pleiades_get_lock, pleiades_release_lock, pleiades_try_lock test */
	CuAssertTrue(tc, !pleiades_get_lock(client, path1, PLEIADES_LOCK_EXCLUSIVE));
   	CuAssertTrue(tc, !pleiades_release_lock(client, path1, PLEIADES_LOCK_EXCLUSIVE));
	CuAssertTrue(tc, !pleiades_try_lock(client, path1, PLEIADES_LOCK_EXCLUSIVE));

	CuAssertTrue(tc, !pleiades_poison(client));
	CuAssertTrue(tc, !pleiades_restart_session(client));

	/* pleiades_set_contents, pleiades_get_contents test */
   	CuAssertTrue(tc, !pleiades_set_contents(client, path2, "this is test"));
  	CuAssertTrue(tc, !pleiades_get_contents(client, path2, 
				contents, sizeof(contents)));
	CuAssertStrEquals(tc, "this is test", contents);

	CuAssertTrue(tc, !pleiades_poison(client));
	CuAssertTrue(tc, !pleiades_restart_session(client));

	/* pleiades_node_exist test */
   	CuAssertTrue(tc, !pleiades_create_file_node(client, path1, "terry001", true));
	CuAssertTrue(tc, !pleiades_node_exist(client, path1));
	CuAssertTrue(tc, !pleiades_delete_node(client, path1, false));
   	CuAssertTrue(tc, !pleiades_create_file_node(client, path2, "terry001", true));
	CuAssertTrue(tc, !pleiades_node_exist(client, path2));
	CuAssertTrue(tc, !pleiades_delete_node(client, path2, false));
	CuAssertTrue(tc, pleiades_node_exist(client, "no_path"));

	/* pleiades_get_meta_data test */
   	CuAssertTrue(tc, !pleiades_create_file_node(client, path2, "terry001", true));
   	metaData = pleiades_get_meta_data(client, path2);
	CuAssertTrue(tc, metaData != NULL);
	gethostname(hostname, sizeof(hostname));
	CuAssertStrEquals(tc, hostname, metaData->creator); 
	CuAssertStrEquals(tc, path2, metaData->lock_id);
	CuAssertIntEquals(tc, 1, metaData->lock_mode);
    printf("generation_number : %ld\n", metaData->generation_number);
   	printf("content_key : %s\n", metaData->content_key);
    pleiades_free_lock_meta_data(metaData, 1);
	CuAssertTrue(tc, !pleiades_delete_node(client, path2, false));

	CuAssertTrue(tc, !pleiades_poison(client));
	CuAssertTrue(tc, !pleiades_restart_session(client));

	/* pleiades_create_file_node, pleiades_delete_node, pleiades_create_dir_node test */
   	CuAssertTrue(tc, !pleiades_create_file_node(client, path3, "terry001", true));
	CuAssertTrue(tc, !pleiades_delete_node(client, path3, false));
	CuAssertTrue(tc, !pleiades_create_dir_node(client, path3, "terry002"));
	CuAssertTrue(tc, !pleiades_delete_node(client, path3, false));

	CuAssertTrue(tc, !pleiades_poison(client));
	CuAssertTrue(tc, !pleiades_restart_session(client));

	/* event handler test */
    handler = pleiades_create_event_handler();
	CuAssertTrue(tc, handler != NULL);
	pleiades_set_contents_modified(handler, contentsModified);
	pleiades_set_node_added(handler, nodeAdded);
	pleiades_set_node_removed(handler, nodeRemoved);
	pleiades_set_node_modified(handler, nodeModified);
	pleiades_set_master_failover(handler, masterFailover);
	pleiades_set_session_warning(handler, sessionWarning);
	pleiades_set_session_safe(handler, sessionSafe);
	pleiades_set_session_expired(handler, sessionExpired);
	pleiades_set_client_expired(handler, clientExpired);
	pleiades_set_lock_expired(handler, lockExpired);
    CuAssertTrue(tc, !pleiades_set_event_handler(client, handler, 0));
   	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data1","terry004",true));

	CuAssertTrue(tc, !pleiades_poison(client));
	CuAssertTrue(tc, !pleiades_restart_session(client));

	/* pleiades_get_children_meta_data test */
	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data1","terry004",true));
	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data2","terry005",true));
	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data3","terry005",true));
	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data4","terry006",true));

	sleep(3);

	if (metaData = 
			pleiades_get_children_meta_data(client, "terry", &numEntries, false)) {
		int idx = 0;
		printf("pleiades_get_children_meta_data:numEntries(%d)\n", numEntries);
		for (idx = 0; idx < numEntries; idx++) {
			fprintf(stderr, "creator : %s\n", metaData[idx].creator);
			fprintf(stderr, "lock_id : %s\n", metaData[idx].lock_id);
			fprintf(stderr, "lock_mode : %d\n", metaData[idx].lock_mode);
			fprintf(stderr, "generation_number : %ld\n", 
					metaData[idx].generation_number);
			fprintf(stderr, "content_key : %s\n", 
					metaData[idx].content_key);
		}

		pleiades_free_lock_meta_data(metaData, numEntries);
	}
	else {
		if (errno) {
			fprintf(stderr, "pleiades_get_children_meta_data FAILED!\n");
			return;
		} 
		else {
		}
	}
	
	pleiades_unset_all_events(handler);
	CuAssertTrue(tc, !pleiades_close_client(client));
	sleep(3); 
	pleiades_close_event_handler(handler);
}

void TestPleiadesEventHandler(CuTest *tc)
{
    pleiades_client_t *client1, *client2; 
	pleiades_event_handler_t *handler1, *handler2;

	client1 = pleiades_create_client("default", NULL);
	CuAssertTrue(tc, client1 != NULL);

	client2 = pleiades_create_client("default", NULL);
	CuAssertTrue(tc, client2 != NULL);

    handler1 = pleiades_create_event_handler();
	CuAssertTrue(tc, handler1 != NULL);

    handler2 = pleiades_create_event_handler();
	CuAssertTrue(tc, handler2 != NULL);

	pleiades_set_node_added(handler1, nodeAdded);
	pleiades_set_node_removed(handler2, nodeRemoved);

    CuAssertTrue(tc, !pleiades_set_event_handler(client1, handler1, 0));
    CuAssertTrue(tc, !pleiades_set_event_handler(client2, handler2, 0));

   	CuAssertTrue(tc, !pleiades_create_file_node(client1, "/a", "tiyun", true));
	CuAssertTrue(tc, !pleiades_delete_node(client2, "/a", false));

	sleep(3);

	CuAssertTrue(tc, !pleiades_close_client(client1));
	CuAssertTrue(tc, !pleiades_close_client(client2));

	pleiades_close_event_handler(handler1);
	pleiades_close_event_handler(handler2);
}

void TestPleiadesEventMasking(CuTest *tc)
{
	pleiades_client_t *client;
	pleiades_event_handler_t *handler;

	client = pleiades_create_client("default", NULL);
	handler = pleiades_create_event_handler();

	pleiades_set_contents_modified(handler, contentsModified);
	pleiades_set_node_added(handler, nodeAdded);
	pleiades_set_node_removed(handler, nodeRemoved);
	pleiades_set_node_modified(handler, nodeModified);
	pleiades_set_master_failover(handler, masterFailover);
	pleiades_set_session_warning(handler, sessionWarning);
	pleiades_set_session_safe(handler, sessionSafe);
	pleiades_set_session_expired(handler, sessionExpired);
	pleiades_set_client_expired(handler, clientExpired);
	pleiades_set_lock_expired(handler, lockExpired);

    CuAssertTrue(tc, !pleiades_set_event_handler(client, handler, 
							PLEIADES_NODE_ADDED | PLEIADES_SESSION_WARNING));

   	CuAssertTrue(tc, !pleiades_create_file_node(client, "/a", "tiyun", true));
	CuAssertTrue(tc, !pleiades_delete_node(client, "/a", false));

	sleep(3);

	CuAssertTrue(tc, !pleiades_close_client(client));
	pleiades_close_event_handler(handler);
}

void TestPleiadesEventFiltering(CuTest *tc) 
{
	pleiades_client_t *client;
	pleiades_event_handler_t *handler;
	pleiades_constraint_t *constraint;
	pleiades_lock_event_filter_t *filter;

	client = pleiades_create_client("default", NULL);
	handler = pleiades_create_event_handler();

	pleiades_set_contents_modified(handler, contentsModified);
	pleiades_set_node_added(handler, nodeAdded);
	pleiades_set_node_removed(handler, nodeRemoved);
	pleiades_set_node_modified(handler, nodeModified);
	pleiades_set_master_failover(handler, masterFailover);
	pleiades_set_session_warning(handler, sessionWarning);
	pleiades_set_session_safe(handler, sessionSafe);
	pleiades_set_session_expired(handler, sessionExpired);
	pleiades_set_client_expired(handler, clientExpired);
	pleiades_set_lock_expired(handler, lockExpired);

	constraint = pleiades_create_constraint();
	pleiades_add_condition(constraint, PLEIADES_PF, "/PREFIX");
	pleiades_add_condition(constraint, PLEIADES_SF, "SUFFIX");
	filter = pleiades_create_lock_event_filter();
	pleiades_add_constraint(filter, constraint);
	pleiades_add_lock_event_monitor(handler, eventMonitor, filter);

    CuAssertTrue(tc, !pleiades_set_event_handler(client, handler, 0));

   	CuAssertTrue(tc, !pleiades_create_file_node(client, "/PREFIX_SUFFIX", "tiyun", true));
	CuAssertTrue(tc, !pleiades_delete_node(client, "/PREFIX_SUFFIX", false));

   	CuAssertTrue(tc, !pleiades_create_file_node(client, "/PREFIX_SUFF", "tiyun", true));
	CuAssertTrue(tc, !pleiades_delete_node(client, "/PREFIX_SUFF", false));

	sleep(3);

	CuAssertTrue(tc, !pleiades_close_client(client));
	pleiades_close_event_handler(handler);
}

void *thread_func(void *arg)
{
	CuTest *tc = (CuTest *)arg;

    const char* path1_prefix = "/a";
    const char* path2_prefix = "/b";
    const char* path3_prefix = "/c"; 
	char path1[256];
	char path2[256];
	char path3[256];
    int result = 0;
	char contents[1024];
	char hostname[256];
	pleiades_lock_meta_data_t *metaData;
    pleiades_client_t *client; 
	pleiades_event_handler_t *handler;
    int numEntries = 0;

	sprintf(path1, "%s%ld", path1_prefix, pthread_self());
	sprintf(path2, "%s%ld", path2_prefix, pthread_self());
	sprintf(path3, "%s%ld", path3_prefix, pthread_self());
	
	client = pleiades_create_client("default", NULL);
	CuAssertTrue(tc, client != NULL);

	/* pleiades_get_lock, pleiades_release_lock, pleiades_try_lock test */
	CuAssertTrue(tc, !pleiades_get_lock(client, path1, PLEIADES_LOCK_EXCLUSIVE));
   	CuAssertTrue(tc, !pleiades_release_lock(client, path1, PLEIADES_LOCK_EXCLUSIVE));
	CuAssertTrue(tc, !pleiades_try_lock(client, path1, PLEIADES_LOCK_EXCLUSIVE));

	/* pleiades_set_contents, pleiades_get_contents test */
   	CuAssertTrue(tc, !pleiades_set_contents(client, path2, "this is test"));
  	CuAssertTrue(tc, !pleiades_get_contents(client, path2, 
				contents, sizeof(contents)));
	CuAssertStrEquals(tc, "this is test", contents);

	/* pleiades_get_meta_data test */
   	metaData = pleiades_get_meta_data(client, path2);
	CuAssertTrue(tc, metaData != NULL);
	gethostname(hostname, sizeof(hostname));
	CuAssertStrEquals(tc, hostname, metaData->creator); 
	CuAssertStrEquals(tc, path2, metaData->lock_id);
	CuAssertIntEquals(tc, 1, metaData->lock_mode);
    printf("generation_number : %ld\n", metaData->generation_number);
   	printf("content_key : %s\n", metaData->content_key);
    pleiades_free_lock_meta_data(metaData, 1);

	/* pleiades_create_file_node, pleiades_delete_node, pleiades_create_dir_node test */
   	CuAssertTrue(tc, !pleiades_create_file_node(client, path3, "terry001", true));
	CuAssertTrue(tc, !pleiades_delete_node(client, path3, false));
	CuAssertTrue(tc, !pleiades_create_dir_node(client, path3, "terry002"));
	CuAssertTrue(tc, !pleiades_delete_node(client, path3, false));

	/* event handler test */
    handler = pleiades_create_event_handler();
	CuAssertTrue(tc, handler != NULL);
	pleiades_set_contents_modified(handler, contentsModified);
	pleiades_set_node_added(handler, nodeAdded);
	pleiades_set_node_removed(handler, nodeRemoved);
	pleiades_set_node_modified(handler, nodeModified);
	pleiades_set_master_failover(handler, masterFailover);
	pleiades_set_session_warning(handler, sessionWarning);
	pleiades_set_session_safe(handler, sessionSafe);
	pleiades_set_session_expired(handler, sessionExpired);
	pleiades_set_client_expired(handler, clientExpired);
	pleiades_set_lock_expired(handler, lockExpired);
    CuAssertTrue(tc, !pleiades_set_event_handler(client, handler, 0));
   	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data1","terry004",true));

	/* getMetaDataList test */
	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data1","terry004",true));
	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data2","terry005",true));
	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data3","terry005",true));
	CuAssertTrue(tc, !pleiades_create_file_node(client,"terry/data4","terry006",true));

	sleep(3);

	if (metaData = 
			pleiades_get_children_meta_data(client, "terry", &numEntries, false)) {
		int idx = 0;
		printf("getMetaDataList:numEntries(%d)\n", numEntries);
		for (idx = 0; idx < numEntries; idx++) {
			fprintf(stderr, "creator : %s\n", metaData[idx].creator);
			fprintf(stderr, "lock_id : %s\n", metaData[idx].lock_id);
			fprintf(stderr, "lock_mode : %d\n", metaData[idx].lock_mode);
			fprintf(stderr, "generation_number : %ld\n", 
					metaData[idx].generation_number);
			fprintf(stderr, "content_key : %s\n", 
					metaData[idx].content_key);
		}

		pleiades_free_lock_meta_data(metaData, numEntries);
	}
	else {
		if (errno) {
			fprintf(stderr, "getMetaDataList FAILED!\n");
			return;
		} 
		else {
		}
	}
	
	//pleiades_unset_all_events(handler);
	CuAssertTrue(tc, !pleiades_close_client(client));
	sleep(1); 
	pleiades_close_event_handler(handler);
}

void *client_shared_thread_func(void *arg)
{
	CuTest *tc = (CuTest *)arg;

    const char* path1_prefix = "/a";
    const char* path2_prefix = "/b";
    const char* path3_prefix = "/c"; 
	char path1[256];
	char path2[256];
	char path3[256];
    int result = 0;
	char contents[1024];
	char hostname[256];
	pleiades_lock_meta_data_t *metaData;
    int numEntries = 0;

	sprintf(path1, "%s%ld", path1_prefix, pthread_self());
	sprintf(path2, "%s%ld", path2_prefix, pthread_self());
	sprintf(path3, "%s%ld", path3_prefix, pthread_self());
	
	CuAssertTrue(tc, shared_client != NULL);

	/* pleiades_get_lock, pleiades_release_lock, pleiades_try_lock test */
	CuAssertTrue(tc, !pleiades_get_lock(shared_client, path1, PLEIADES_LOCK_EXCLUSIVE));
   	CuAssertTrue(tc, !pleiades_release_lock(shared_client, path1, PLEIADES_LOCK_EXCLUSIVE));
	CuAssertTrue(tc, !pleiades_try_lock(shared_client, path1, PLEIADES_LOCK_EXCLUSIVE));

	/* pleiades_set_contents, pleiades_get_contents test */
   	CuAssertTrue(tc, !pleiades_set_contents(shared_client, path2, "this is test"));
  	CuAssertTrue(tc, !pleiades_get_contents(shared_client, path2, 
				contents, sizeof(contents)));
	CuAssertStrEquals(tc, "this is test", contents);

	/* pleiades_get_meta_data test */
   	metaData = pleiades_get_meta_data(shared_client, path2);
	CuAssertTrue(tc, metaData != NULL);
	gethostname(hostname, sizeof(hostname));
	CuAssertStrEquals(tc, hostname, metaData->creator); 
	CuAssertStrEquals(tc, path2, metaData->lock_id);
	CuAssertIntEquals(tc, 1, metaData->lock_mode);
    printf("generation_number : %ld\n", metaData->generation_number);
   	printf("content_key : %s\n", metaData->content_key);
    pleiades_free_lock_meta_data(metaData, 1);

	/* pleiades_create_file_node, pleiades_delete_node, pleiades_create_dir_node test */
   	CuAssertTrue(tc, !pleiades_create_file_node(shared_client, path3, "terry001", true));
	CuAssertTrue(tc, !pleiades_delete_node(shared_client, path3, false));
	CuAssertTrue(tc, !pleiades_create_dir_node(shared_client, path3, "terry002"));
	CuAssertTrue(tc, !pleiades_delete_node(shared_client, path3, false));

   	CuAssertTrue(tc, !pleiades_create_file_node(shared_client,"terry/data1","terry004",true));

	/* getMetaDataList test */
	CuAssertTrue(tc, !pleiades_create_file_node(shared_client,"terry/data1","terry004",true));
	CuAssertTrue(tc, !pleiades_create_file_node(shared_client,"terry/data2","terry005",true));
	CuAssertTrue(tc, !pleiades_create_file_node(shared_client,"terry/data3","terry005",true));
	CuAssertTrue(tc, !pleiades_create_file_node(shared_client,"terry/data4","terry006",true));

	sleep(3);

	if (metaData = 
			pleiades_get_children_meta_data(shared_client, "terry", &numEntries, false)) {
		int idx = 0;
		printf("getMetaDataList:numEntries(%d)\n", numEntries);
		for (idx = 0; idx < numEntries; idx++) {
			fprintf(stderr, "creator : %s\n", metaData[idx].creator);
			fprintf(stderr, "lock_id : %s\n", metaData[idx].lock_id);
			fprintf(stderr, "lock_mode : %d\n", metaData[idx].lock_mode);
			fprintf(stderr, "generation_number : %ld\n", 
					metaData[idx].generation_number);
			fprintf(stderr, "content_key : %s\n", 
					metaData[idx].content_key);
		}

		pleiades_free_lock_meta_data(metaData, numEntries);
	}
	else {
		if (errno) {
			fprintf(stderr, "getMetaDataList FAILED!\n");
			return;
		} 
		else {
		}
	}
}

#define THREAD_CNT 8 
void TestThreadSafety(CuTest *tc)
{
	pthread_t tid[THREAD_CNT];
	int i;

	for (i = 0; i < THREAD_CNT; i++) 
		pthread_create(&tid[i], NULL, thread_func, (void *)tc);

	for (i = 0; i < THREAD_CNT; i++)
		pthread_join(tid[i], NULL);
}

void TestSharedClientHandleThreadSafety(CuTest *tc)
{
	pthread_t tid[THREAD_CNT];
	int i;

	for (i = 0; i < THREAD_CNT; i++) 
		pthread_create(&tid[i], NULL, client_shared_thread_func, (void *)tc);

	for (i = 0; i < THREAD_CNT; i++)
		pthread_join(tid[i], NULL);
}

void TestPoisonRestartSession(CuTest *tc) 
{
	pleiades_client_t *client;
	pleiades_event_handler_t *handler;

	client = pleiades_create_client("default", NULL);

	CuAssertTrue(tc, !pleiades_poison(client));
	CuAssertTrue(tc, !pleiades_restart_session(client));

	handler = pleiades_create_event_handler();

	pleiades_set_contents_modified(handler, contentsModified);
	pleiades_set_node_added(handler, nodeAdded);
	pleiades_set_node_removed(handler, nodeRemoved);
	pleiades_set_node_modified(handler, nodeModified);
	pleiades_set_master_failover(handler, masterFailover);
	pleiades_set_session_warning(handler, sessionWarning);
	pleiades_set_session_safe(handler, sessionSafe);
	pleiades_set_session_expired(handler, sessionExpired);
	pleiades_set_client_expired(handler, clientExpired);
	pleiades_set_lock_expired(handler, lockExpired);

	CuAssertTrue(tc, !pleiades_poison(client));
	CuAssertTrue(tc, !pleiades_restart_session(client));

    CuAssertTrue(tc, !pleiades_set_event_handler(client, handler, 0));

	CuAssertTrue(tc, !pleiades_poison(client));
	CuAssertTrue(tc, !pleiades_restart_session(client));

   	CuAssertTrue(tc, !pleiades_create_file_node(client, "/tiyun", "tiyun", true));
	CuAssertTrue(tc, !pleiades_delete_node(client, "/tiyun", false));

	sleep(3);

	CuAssertTrue(tc, !pleiades_close_client(client));
	pleiades_close_event_handler(handler);
}

CuSuite *CuGetSuite(void)
{
	CuSuite *suite = CuSuiteNew();

	SUITE_ADD_TEST(suite, TestPleiades);
	SUITE_ADD_TEST(suite, TestPoisonRestartSession);
 	SUITE_ADD_TEST(suite, TestPleiadesEventHandler);
	SUITE_ADD_TEST(suite, TestPleiadesEventMasking);
	SUITE_ADD_TEST(suite, TestPleiadesEventFiltering);
	SUITE_ADD_TEST(suite, TestThreadSafety);
	SUITE_ADD_TEST(suite, TestSharedClientHandleThreadSafety);

	return suite;
}

int main (int argc, const char** argv)
{
	CuString *output = CuStringNew();
	CuSuite *suite = CuSuiteNew();

	CuSuiteAddSuite(suite, CuGetSuite());

	shared_client = pleiades_create_client("default", NULL);
    shared_handler = pleiades_create_event_handler();

	pleiades_set_contents_modified(shared_handler, contentsModified);
	pleiades_set_node_added(shared_handler, nodeAdded);
	pleiades_set_node_removed(shared_handler, nodeRemoved);
	pleiades_set_node_modified(shared_handler, nodeModified);
	pleiades_set_master_failover(shared_handler, masterFailover);
	pleiades_set_session_warning(shared_handler, sessionWarning);
	pleiades_set_session_safe(shared_handler, sessionSafe);
	pleiades_set_session_expired(shared_handler, sessionExpired);
	pleiades_set_client_expired(shared_handler, clientExpired);
	pleiades_set_lock_expired(shared_handler, lockExpired);
    pleiades_set_event_handler(shared_client, shared_handler, 0);

	CuSuiteRun(suite);

	pleiades_close_client(shared_client);
	pleiades_close_event_handler(shared_handler);

	CuSuiteSummary(suite, output);
	CuSuiteDetails(suite, output);
	printf("%s\n", output->buffer);

	return 0;
}

